package com.tuyan.aixiang.activity.home.control;

import android.content.Intent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.services.weather.LocalWeatherForecastResult;
import com.amap.api.services.weather.LocalWeatherLiveResult;
import com.amap.api.services.weather.WeatherSearch;
import com.amap.api.services.weather.WeatherSearchQuery;
import com.google.android.flexbox.FlexboxLayout;
import com.tuyan.aixiang.R;
import com.tuyan.aixiang.activity.fullplayer.FullPlayerActivity;
import com.tuyan.aixiang.activity.home.Home;
import com.tuyan.aixiang.activity.qr.NewQrScanActivity;
import com.tuyan.aixiang.api.HttpClient;
import com.tuyan.aixiang.api.helper.ResultTransformer;
import com.tuyan.aixiang.api.helper.RxSchedulers;
import com.tuyan.aixiang.common.BaseFragment;
import com.tuyan.aixiang.common.Constant;
import com.tuyan.aixiang.common.StorageKey;
import com.tuyan.aixiang.common.lang.ListHelper;
import com.tuyan.aixiang.component.ControlPanel;
import com.tuyan.aixiang.component.DeviceListTitle;
import com.tuyan.aixiang.component.ModeItem;
import com.tuyan.aixiang.component.SensorItem;
import com.tuyan.aixiang.component.VidItem;
import com.tuyan.aixiang.component.VidOperateDialog;
import com.tuyan.aixiang.component.WeatherPanel;
import com.tuyan.aixiang.model.Event;
import com.tuyan.aixiang.model.Mode;
import com.tuyan.aixiang.model.ShortCut;
import com.tuyan.aixiang.model.YsDevice;
import com.tuyan.aixiang.util.Log;
import com.tuyan.aixiang.util.StorageUtil;
import com.tuyan.aixiang.util.ToastUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.disposables.Disposable;

public class ControlFragment extends BaseFragment<ControlPresenter> implements Control.View{

    private static final String TAG = "ControlFragment";
    
    @BindView(R.id.cp_panel)
    ControlPanel cpPanel;

    @BindView(R.id.v_status_holder)
    View vStatusHolder;

    @BindView(R.id.ll_mode)
    FlexboxLayout llModeContainer;

    @BindView(R.id.ll_vid_container)
    LinearLayout llVidContainer;

    @BindView(R.id.ll_vid_wrapper)
    LinearLayout llVidWrapper;

    @BindView(R.id.ll_sensor_container)
    LinearLayout llSensorContainer;

    @BindView(R.id.ll_no_device)
    LinearLayout llNoDevice;

    @BindView(R.id.vid_title)
    DeviceListTitle dltVid;

    @BindView(R.id.sensor_title)
    DeviceListTitle dltSensor;

    @BindView(R.id.sensor_col_1)
    LinearLayout sensorCol1;

    @BindView(R.id.sensor_col_2)
    LinearLayout sensorCol2;

    @BindView(R.id.wp_panel)
    WeatherPanel wpPanel;

//    @BindView(R.id.fbl_sensor_container)
//    FlexboxLayout fblSensorContainer;

    private VidOperateDialog vidOperateDialog;

    private Home homeActivity;

    //声明AMapLocationClient类对象
    private AMapLocationClient mLocationClient = null;



    public void setContainer(Home h) {
        this.homeActivity = h;
    }


    @Override
    protected void initView(View contentView) {
        // bind EventBus
        EventBus.getDefault().register(this);

        initStatusHolder();
        vidOperateDialog = new VidOperateDialog(getContext());
        vidOperateDialog.setOnToggleDetect((serial, code) -> {
            showLoading();
            Integer failCode = code.equals(1)  ? 0: 1;
            Disposable disposable = HttpClient.getDevice().setDefence(serial, code)
                    .compose(RxSchedulers.io_main())
                    .compose(ResultTransformer.handleResult())
                    .subscribe(r -> {
                        hideLoading();
                        ToastUtil.makeShort("活动检测设置成功");
                        vidOperateDialog.syncToggleDetect(code);
                    }, throwable -> {
                        hideLoading();
                        ToastUtil.makeShort("活动检测设置失败");
                        vidOperateDialog.syncToggleDetect(failCode);
                    });
            addDisposable(disposable);
        });
        wpPanel.setRefreshCallback(this::fetchWeather);


    }

    private void fetchWeather() {
        wpPanel.loadWeather(null);

        homeActivity.withLocationPermission(() -> {
            AMapLocationListener mLocationListener = aMapLocation -> {
                if (aMapLocation != null) {
                    if (aMapLocation.getErrorCode() == 0) {
                        //可在其中解析amapLocation获取相应内容。
                        WeatherSearchQuery query = new WeatherSearchQuery(aMapLocation.getCity(), WeatherSearchQuery.WEATHER_TYPE_LIVE);
                        WeatherSearch search = new WeatherSearch(getActivity());
                        search.setOnWeatherSearchListener(new WeatherSearch.OnWeatherSearchListener() {
                            @Override
                            public void onWeatherLiveSearched(LocalWeatherLiveResult localWeatherLiveResult, int code) {
                                if(code == 1000) {
                                    Log.d(TAG, "getWeather success");
                                    if(null == getActivity()) return;
                                    getActivity().runOnUiThread(() -> {
                                        wpPanel.loadWeather(localWeatherLiveResult.getLiveResult());
                                    });
                                } else {
                                    if(null == getActivity()) return;
                                    getActivity().runOnUiThread(() -> {
                                        ToastUtil.makeShort("天气信息获取失败");
                                        wpPanel.loadWeather(null);
                                    });
                                }
                            }

                            @Override
                            public void onWeatherForecastSearched(LocalWeatherForecastResult localWeatherForecastResult, int i) {

                            }
                        });
                        search.setQuery(query);
                        search.searchWeatherAsyn();

                    } else {
                        //定位失败时，可通过ErrCode（错误码）信息来确定失败的原因，errInfo是错误信息，详见错误码表。
                    }
                }
            };
            //初始化定位
            mLocationClient = new AMapLocationClient(getActivity());
            //设置定位回调监听
            mLocationClient.setLocationListener(mLocationListener);
            //初始化AMapLocationClientOption对象
            AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
            //设置定位模式为AMapLocationMode.Hight_Accuracy，高精度模式。
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //获取一次定位结果：
            //该方法默认为false。
            mLocationOption.setOnceLocation(true);

            mLocationOption.setNeedAddress(true);
            //获取最近3s内精度最高的一次定位结果：
            //设置setOnceLocationLatest(boolean b)接口为true，启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true，setOnceLocation(boolean b)
            // 接口也会被设置为true，反之不会，默认为false。
            mLocationOption.setOnceLocationLatest(true);

            //单位是毫秒，默认30000毫秒，建议超时时间不要低于8000毫秒。
            mLocationOption.setHttpTimeOut(20000);
            //关闭缓存机制
            mLocationOption.setLocationCacheEnable(false);
            //给定位客户端对象设置定位参数
            mLocationClient.setLocationOption(mLocationOption);
            //启动定位
            mLocationClient.startLocation();
        });
    }


    @Override
    public void onResume() {
        super.onResume();
        iPresenter.refetch();
        fetchWeather();
    }

    @Override
    public void initNoDevice() {
        llVidContainer.setVisibility(View.GONE);
        llSensorContainer.setVisibility(View.GONE);
        llNoDevice.setVisibility(View.VISIBLE);
    }


    private void initStatusHolder() {
        Integer height = getStatusBarOffset();
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height);
        vStatusHolder.setLayoutParams(lp);
    }

    private void handleOnModeChange(ModeItem mi) {
        Log.d(TAG, "mode change");
    }


    @Override
    protected int getLayoutId() {
        return R.layout.fragment_control;
    }

    @Override
    protected ControlPresenter createPresenter() {
        return new ControlPresenter();
    }

    @OnClick(R.id.ll_search)
    public void search() {
        openWeb(Constant.DEVICE_SEARCH);
    }

    @OnClick({R.id.iv_add_device, R.id.ll_add_device})
    public void addDevice() {
        homeActivity.withCameraPermission(() -> {
//            startActivity(new Intent(getActivity(), QrScanActivity.class));
            startActivity(new Intent(getActivity(), NewQrScanActivity.class));
        });
    }

    @Override
    public void loadModeList(List<Mode> modes) {
        llModeContainer.removeAllViews();

        for(int i = 0; i < modes.size(); i ++) {
            ModeItem mi = new ModeItem(getContext());
            mi.setup(modes.get(i));
            llModeContainer.addView(mi);
            mi.setOnClickListener(v -> {
//                for (ModeItem modeItem : modeItems) {
//                    modeItem.uncheck();
//                }
                mi.check();
                handleOnModeChange(mi);
            });
        }
        // TODO saved check
//        modeHome.check();
    }

    @Override
    public void loadVidPanel(List<YsDevice> devices) {
        if(devices.size() == 0) return;
        llVidContainer.setVisibility(View.VISIBLE);
        llNoDevice.setVisibility(View.GONE);
        llVidWrapper.removeAllViews();
//        dltVid.setCount(devices.size());
        dltVid.setLinkClick(() -> {
            openWeb(Constant.DEVICE_LIST + "?model=CAMERA");
        });

        ListHelper.forEach(devices, device -> {
            VidItem vidItem = new VidItem(getContext());
            vidItem.setup(device);
            vidItem.onMoreClick(() -> {
                vidOperateDialog.show(device, vidItem);
            });
            vidItem.onCoverClick(() -> {
                if(device.getOnlineStatus().equals(1)) {
//                PlayerActivity.startPlayActivity(getContext(),device);
                    FullPlayerActivity.startPlayActivity(getContext(), device);
                } else {
                    ToastUtil.makeShort("设备不在线");
                }
            });
            vidOperateDialog.setOnRefresh(vi -> {
                vi.refresh();
                vidOperateDialog.hide();
            });
            vidOperateDialog.setOnSetting(d -> {
                openWeb(Constant.CAMERA_SETTING + "?id=" + d.getId());
                vidOperateDialog.hide();
            });
            llVidWrapper.addView(vidItem);
        });


    }

    @Override
    public void loadSensorPanel(List<YsDevice> devices) {
        if(devices.size() == 0) return;

//        llVidContainer.setVisibility(View.VISIBLE);
        llSensorContainer.setVisibility(View.VISIBLE);
        llNoDevice.setVisibility(View.GONE);
//        fblSensorContainer.removeAllViews();
        sensorCol1.removeAllViews();
        sensorCol2.removeAllViews();
//        dltSensor.setCount(devices.size());
        dltSensor.setLinkClick(() -> {
          openWeb(Constant.DEVICE_LIST + "?model=ALARM");
        });
        ListHelper.forEach(devices, (device, index) -> {
            SensorItem sensorItem = new SensorItem(getContext());
            sensorItem.setup(device);
            sensorItem.onClick(() -> {
                if(device.getModel().equals(Constant.MODEL_SOCKET)) {
                    openWeb(Constant.SOCKET_DETAIL + "?id=" + device.getId());
                } else {
                    openWeb(Constant.ALARM_DETAIL + "?id=" + device.getId());
                }
            });
            if(index % 2  == 0) {
                sensorCol1.addView(sensorItem);
            } else {
                sensorCol2.addView(sensorItem);
            }
        });

    }

    @Override
    public void loadControlPanel(List<ShortCut> shortCuts) {

        cpPanel.setup(shortCuts);
        cpPanel.setOnShortCutClick(shortCut -> {
            if(shortCut.isShowMsgCount()) {
                StorageUtil.setBoolean(StorageKey.HAS_NEW_MSG, false);
            }
            openWeb(shortCut.getUrl());
        });
        if(StorageUtil.getBoolean(StorageKey.HAS_NEW_MSG, false)) {
            cpPanel.updateMsgCount(1);
        } else {
            cpPanel.updateMsgCount(0);
        }
    }

    @Override
    public void showSensorSize(Integer size) {
        dltSensor.setCount(size);
    }

    @Override
    public void showVidSize(Integer size) {
        dltVid.setCount(size);
    }

    @Override
    public void loadWeatherInfo() {

    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onGetMessage(Event event) {
        if(event.getType().equals(Event.EventType.NEW_MSG)) {
            if(null != cpPanel) {
                if(StorageUtil.getBoolean(StorageKey.HAS_NEW_MSG, false)) {
                    cpPanel.updateMsgCount(1);
                }
            }
        }
    }
}